home *** CD-ROM | disk | FTP | other *** search
- ############################################################################
- #
- # Name: empg.icn
- #
- # Title: Expression Measurement Program Generator
- #
- # Author: Ralph E. Griswold
- #
- # Date: March 8, 1990
- #
- ############################################################################
- #
- # This program reads Icon expressions, one per line, and writes out
- # and Icon program, which when run, times the expressions and reports
- # average evaluation time and storage allocation.
- #
- # Lines beginning with a # are treated as comments and written to the
- # output program so as to be written as comments when the output program is
- # run.
- #
- # Lines beginning with a : are passed to the output program to be
- # evaluated, but not timed.
- #
- # Lines beginning with a $ are included at the end of the output
- # program as declarations.
- #
- # All other lines are timed in loops.
- #
- # An example of input is:
- #
- # :T := table(0)
- # $record complex(r,i)
- # T[1]
- # complex(0.0,0.0)
- #
- # The resulting output program evaluates the expressions on the last two
- # lines and reports their average time and storage allocation.
- #
- # Loop overhead for timing is computed first. The default number of
- # iterations s 10000. A different number can be given on the command line
- # when empg is executed, as in
- #
- # iconx empg 1000 <test.exp >test.icn
- #
- # which takes expressions from test.exp, computes loop overhead using 1000
- # iterations, and writes the measurement program to test.icn.
- #
- # The default number of iterations for timing expressions is 1000. A
- # different number can be given on the command line when the measurement
- # program is run, as in
- #
- # icont test
- # iconx test 5000
- #
- # which times the expressions in test.icn using 5000 iterations.
- #
- # If a garbage collection occurs during timing, the average time is
- # likely to be significantly distorted and average allocation cannot be
- # computed. In this case, the number of garbage collections is reported
- # instead. To avoid misleading results as a consequence, measurement
- # programs should be run with Icon's region sizes set to as large values
- # as possible. To avoid residual effects of one timed expression on
- # another, expressions that allocate significant amounts of storage
- # should be measured in separate programs.
- #
- # The number of iterations used to compute loop overhead im empg
- # and the number of iterations used to time expressions in measurement
- # programs should be chosen so that the effects of low clock resolution
- # are minimized. In particular, systems with very fast CPUs but
- # low clock resolution (like 386 and 486 processors running under
- # MS-DOS) need large values.
- #
- ############################################################################
- #
- # Links: numbers (in measurement programs, not in empg.icn)
- #
- ############################################################################
-
- procedure main(argl)
- local i, decls, line, input
- i := integer(argl[1]) | 10000
- decls := [] # list for declarations
- write("link numbers")
- write("global _Count, _Coll, _Store, _Overhead, _Names")
- write("procedure main(argl)")
- write(" _Iter := argl[1] | 1000")
- write(" _Names := [\"static\",\"string\",\"block \"]")
- write(" write(\"iterations: \",_Iter)")
- write(" write(\"&version: \",&version)")
- write(" write(\"&host: \",&host)")
- write(" write(\"&dateline: \",&dateline)")
- write(" write(\"region sizes: \")")
- write(" _I := 1")
- write(" every _S := ®ions do {")
- write(" write(\" \",_Names[_I],\" \",_S)")
- write(" _I +:= 1")
- write(" }")
- write(" _Count := ",i)
- write(" _Itime := &time")
- write(" every 1 to _Count do { &null }")
- write(" _Overhead := real(&time - _Itime) / _Count")
- write(" _Itime := &time")
- write(" every 1 to _Count do { &null & &null }")
- write(" _Overhead := real(&time - _Itime) / _Count - _Overhead")
- write(" _Count := _Iter")
- while line := read(input) do
- case line[1] of {
- ":": { # evaluate but do not time
- write(" ",line[2:0])
- write(" write(",image(line[2:0]),")")
- }
- "$": { # line of declaration
- put(decls,line[2:0])
- write(" write(",image(line[2:0]),")")
- }
- "#": # comment
- write(" write(",image(line),")")
- default: { # time in a loop
- write(" write(",image(line),")")
- write(" _Prologue()")
- write(" _Itime := &time")
- write(" every 1 to _Count do {")
- write(" &null & ", line)
- write(" }")
- write(" _Epilogue(&time - _Itime)")
- }
- }
- write("end")
- write("procedure _Prologue()")
- write(" _Store := []")
- write(" _Coll := []")
- write(" collect()")
- write(" every put(_Store,&storage)")
- write(" every put(_Coll,&collections)")
- write("end")
- write("procedure _Epilogue(_Time)")
- write(" every put(_Store,&storage)")
- write(" every put(_Coll,&collections)")
- write(" write(fix(real(_Time) / _Count - _Overhead,1,8),\" ms.\")")
- write(" if _Coll[1] = _Coll[5] then {")
- write(" write(\"average allocation:\",)")
- write(" every _I := 1 to 3 do")
- write(" write(\" \",_Names[_I],fix(real(_Store[_I + 3] - _Store[_I]),_Count,12))")
- write(" }")
- write(" else {")
- write(" write(\"garbage collections:\")")
- write(" write(\" total \",right(_Coll[5] - _Coll[1],4))")
- write(" every _I := 6 to 8 do write(\" \",_Names[_I - 5],right(_Coll[_I] - _Coll[_I - 4],4))")
- write(" }")
- write(" write()")
- write("end")
- every write(!decls) # write out declarations
- end
-